package com.xtt._04_Apache.commons_Lang;

import org.apache.commons.lang3.*;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.junit.Test;

import java.io.*;
import java.util.*;

/**
 * @Author xtt.
 * @Description: http://tool.oschina.net/apidocs/apidoc?api=commons-lang 文档
 *                  http://commons.apache.org/proper/commons-lang/javadocs/api-release/index.html
 * @Date:Create in 2017/9/25 0025 上午 11:03
 * @Modify By:
 */
public class LangTest {
    /**
     * CharSet
     */
    @Test
    public void charSetDemo() {
        System.out.println("**CharSet 字符集**");

        System.out.println(CharSet.getInstance(""));//[]
        CharSet charSet1 = CharSet.getInstance("a-e");//字符从a到e
        System.out.println(charSet1);//[a-e]
        System.out.println(charSet1.contains('b'));//true

        CharSet charSet2 = CharSet.getInstance("^a");//非a字符
        System.out.println(charSet2);//[^a]
        System.out.println(charSet2.contains('a'));//false
        System.out.println(charSet2.contains('b'));//true


        CharSet charSet3 = CharSet.getInstance("^a-e");//非a-e
        System.out.println(charSet3);//[^a-e]
        System.out.println(charSet3.contains('a'));//false
        System.out.println(charSet3.contains('b'));//false
        System.out.println(charSet3.contains('f'));//true


        CharSet charSet4 = CharSet.getInstance("abe-g");//
        System.out.println(charSet4);//[b, e-g, a]
        System.out.println(charSet4.contains('c'));//false
        System.out.println(charSet4.contains('f'));//true


        CharSet charSet = CharSet.getInstance("aeiou");
        String demoStr = "The quick brown fox jumps over the lazy dog.";
        int count = 0;
        for (int i = 0, len = demoStr.length(); i < len; i++) {
            if (charSet.contains(demoStr.charAt(i))) {
                count++;
            }
        }
        System.out.println("count: " + count);
    }

    /**
     * CharSetUtils
     */
    @Test
    public void charSetUtilsDemo() {
        System.out.println("**CharSetUtils**");
        System.out.println("计算字符串中包含某字符数.");
        System.out.println(CharSetUtils.count(
                "The quick brown fox jumps over the lazy dog.", "aeiou"));

        System.out.println("删除字符串中某字符.");
        System.out.println(CharSetUtils.delete(
                "The quick brown fox jumps over the lazy dog.", "aeiou"));

        System.out.println("保留字符串中某字符.");
        System.out.println(CharSetUtils.keep(
                "The quick brown fox jumps over the lazy dog.", "aeiou"));

        System.out.println("合并重复的字符.");
        System.out.println(CharSetUtils.squeeze("a  bbbbbb     c dd", "b d"));
    }

    /**
     * charUtils
     */
    @Test
    public void charUtilsDemo(){
        System.out.println(CharUtils.toChar("a"));
        System.out.println(CharUtils.toChar("abc"));
        System.out.println(CharUtils.toChar("",'a'));//带默认值
        System.out.println(CharUtils.toIntValue('A',-1));//-1
        System.out.println(CharUtils.toIntValue('3',0));//带默认值

    }

    /**
     * ObjectUtils
     */
    @Test
    public void objectUtilsDemo() {
        System.out.println("**ObjectUtilsDemo**");
        System.out.println("Object为null时，默认打印某字符.");
        Object obj = null;
        System.out.println(ObjectUtils.defaultIfNull(obj, "空"));
        /*ObjectUtils.allNotNull(*)             = true
         ObjectUtils.allNotNull(*, *)          = true
         ObjectUtils.allNotNull(null)          = false
         ObjectUtils.allNotNull(null, null)    = false
         ObjectUtils.allNotNull(null, *)       = false
         ObjectUtils.allNotNull(*, null)       = false
         ObjectUtils.allNotNull(*, *, null, *) = false*/

        /*ObjectUtils.anyNotNull(*)                = true
         ObjectUtils.anyNotNull(*, null)          = true
         ObjectUtils.anyNotNull(null, *)          = true
         ObjectUtils.anyNotNull(null, null, *, *) = true
         ObjectUtils.anyNotNull(null)             = false
         ObjectUtils.anyNotNull(null, null)       = false
         */

        System.out.println("验证两个引用是否指向的Object是否相等,取决于Object的equals()方法.");
        Object a = new Object();
        Object b = a;
        Object c = new Object();
//        System.out.println(ObjectUtils.equals(a, b));//@Deprecated
//        System.out.println(ObjectUtils.equals(a, c));//@Deprecated
        System.out.println(Objects.equals(a,b));
        System.out.println(Objects.equals(a,c));

        System.out.println("用父类Object的toString()方法返回对象信息.");
        Date date = new Date();
        System.out.println(ObjectUtils.identityToString(date));
        System.out.println(date);

        System.out.println("返回类本身的toString()方法结果,");
//        System.out.println(ObjectUtils.toString(date));//@Deprecated
//        System.out.println(ObjectUtils.toString(null));//对象为null时，返回0长度字符串.
        System.out.println(Objects.toString(date));
        System.out.println(Objects.toString(null));//null
        System.out.println(date);
    }

    /**
     * SerializetionUtils 系列化
     */
    @Test
    public void serializationUtilsDemo() {
        System.out.println("*SerializationUtils**");
        Date date = new Date();
        byte[] bytes = SerializationUtils.serialize(date);
        System.out.println(ArrayUtils.toString(bytes));
        System.out.println(date);

        Date reDate = SerializationUtils.deserialize(bytes);
        System.out.println(reDate);
        System.out.println(Objects.equals(date, reDate));
        System.out.println(date == reDate);

        FileOutputStream fos = null;
        FileInputStream fis = null;
        try {
            fos = new FileOutputStream(new File("d:/test.txt"));
            fis = new FileInputStream(new File("d:/test.txt"));
            SerializationUtils.serialize(date, fos);
            Date reDate2 = (Date) SerializationUtils.deserialize(fis);

            System.out.println(date.equals(reDate2));

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                fos.close();
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     *  RandomStringUtils 废弃
     */
//    @Test
//    public void randomStringUtilsDemo() {
//        System.out.println("**RandomStringUtilsDemo**");
//        System.out.println("生成指定长度的随机字符串,好像没什么用.");
//        System.out.println(RandomStringUtils.random(500));
//
//        System.out.println("在指定字符串中生成长度为n的随机字符串.");
//        System.out.println(RandomStringUtils.random(5, "abcdefghijk"));
//
//        System.out.println("指定从字符或数字中生成随机字符串.");
//        System.out.println(RandomStringUtils.random(5, true, false));
//        System.out.println(RandomStringUtils.random(5, false, true));
//
//    }

    /**
     *StringUtils
     */
    @Test
    public void stringUtilsDemo() {
        System.out.println("**StringUtils**");
        System.out.println("IsEmpty/IsBlank - checks if a String contains text");
        System.out.println(StringUtils.isEmpty(""));//true
        System.out.println(StringUtils.isEmpty(" "));//false
        System.out.println(StringUtils.isEmpty(null));//true
        System.out.println(StringUtils.isBlank(""));//true
        System.out.println(StringUtils.isBlank(" "));//true
        System.out.println(StringUtils.isBlank(null));//true

        System.out.println("Trim/Strip - removes leading and trailing whitespace");
        System.out.println(StringUtils.trim("   123"));//123
        System.out.println(StringUtils.trimToEmpty("   "));//
        System.out.println(StringUtils.trimToNull("   "));//null
        System.out.println(StringUtils.strip("123     "));//123

        System.out.println("Equals/Compare - compares two strings null-safe");
        System.out.println(StringUtils.equalsAny("123","123","123"));
        System.out.println(StringUtils.equalsAnyIgnoreCase("abc","abC","ABC"));
        System.out.println(StringUtils.equalsIgnoreCase("abc","ABC"));

        System.out.println("startsWith - check if a String starts with a prefix null-safe");
        System.out.println("endsWith - check if a String ends with a suffix null-safe");
        System.out.println("IndexOf/LastIndexOf/Contains - null-safe index-of checks");

        System.out.println("IndexOfAny/LastIndexOfAny/IndexOfAnyBut - index-of any of a set of Strings");
        System.out.println(StringUtils.indexOfAny("abcdefg","a","g"));//0
        System.out.println(StringUtils.lastIndexOfAny("abcdefg","a","g"));//6
        System.out.println(StringUtils.indexOfAnyBut("abcdefg","a"));//1

        System.out.println("ContainsOnly/ContainsNone/ContainsAny - does String contains only/none/any of these characters");

        System.out.println("SubstringBefore/SubstringAfter/SubstringBetween - substring extraction relative to other strings");
        System.out.println(StringUtils.substringAfter("12556","5"));//56
        System.out.println(StringUtils.substringBefore("123456","5"));//1234
        System.out.println(StringUtils.substringBeforeLast("125456","5"));//1254
        System.out.println(StringUtils.substringBetween("125456","5"));//4
        Arrays.stream(StringUtils.substringsBetween("125456","2","6")).forEach(System.out::println);//545

        System.out.println("Split/Join - splits a String into an array of substrings and vice versa");
        System.out.println("Remove/Delete - removes part of a String");
        System.out.println("Replace/Overlay - Searches a String and replaces one String with another");
//        StringUtils.overlay(null, *, *, *)            = null
//        StringUtils.overlay("", "abc", 0, 0)          = "abc"
//        StringUtils.overlay("abcdef", null, 2, 4)     = "abef"
//        StringUtils.overlay("abcdef", "", 2, 4)       = "abef"
//        StringUtils.overlay("abcdef", "", 4, 2)       = "abef"
//        StringUtils.overlay("abcdef", "zzzz", 2, 4)   = "abzzzzef"
//        StringUtils.overlay("abcdef", "zzzz", 4, 2)   = "abzzzzef"
//        StringUtils.overlay("abcdef", "zzzz", -1, 4)  = "zzzzef"
//        StringUtils.overlay("abcdef", "zzzz", 2, 8)   = "abzzzz"
//        StringUtils.overlay("abcdef", "zzzz", -2, -3) = "zzzzabcdef"
//        StringUtils.overlay("abcdef", "zzzz", 8, 10)  = "abcdefzzzz"


        System.out.println("AppendIfMissing - appends a suffix to the end of the String if not present");

        System.out.println("PrependIfMissing - prepends a prefix to the start of the String if not present");
        System.out.println("LeftPad/RightPad/Center/Repeat - pads a String");
//       StringUtils.leftPad(null, *, *)      = null
//        StringUtils.leftPad("", 3, "z")      = "zzz"
//        StringUtils.leftPad("bat", 3, "yz")  = "bat"
//        StringUtils.leftPad("bat", 5, "yz")  = "yzbat"
//        StringUtils.leftPad("bat", 8, "yz")  = "yzyzybat"
//        StringUtils.leftPad("bat", 1, "yz")  = "bat"
//        StringUtils.leftPad("bat", -1, "yz") = "bat"
//        StringUtils.leftPad("bat", 5, null)  = "  bat"
//        StringUtils.leftPad("bat", 5, "")    = "  bat"
        System.out.println("UpperCase/LowerCase/SwapCase/Capitalize/Uncapitalize - changes the case of a String");
        System.out.println("CountMatches - counts the number of occurrences of one String in another");
//        StringUtils.countMatches(null, *)       = 0
//        StringUtils.countMatches("", *)         = 0
//        StringUtils.countMatches("abba", null)  = 0
//        StringUtils.countMatches("abba", "")    = 0
//        StringUtils.countMatches("abba", "a")   = 2
//        StringUtils.countMatches("abba", "ab")  = 1
//        StringUtils.countMatches("abba", "xxx") = 0
        System.out.println("IsAlpha/IsNumeric/IsWhitespace/IsAsciiPrintable - checks the characters in a String");
        System.out.println("DefaultString - protects against a null input String");
        System.out.println("Rotate - rotate (circular shift) a String");
//        StringUtils.rotate(null, *)        = null
//        StringUtils.rotate("", *)          = ""
//        StringUtils.rotate("abcdefg", 0)   = "abcdefg"
//        StringUtils.rotate("abcdefg", 2)   = "fgabcde"
//        StringUtils.rotate("abcdefg", -2)  = "cdefgab"
//        StringUtils.rotate("abcdefg", 7)   = "abcdefg"
//        StringUtils.rotate("abcdefg", -7)  = "abcdefg"
//        StringUtils.rotate("abcdefg", 9)   = "fgabcde"
//        StringUtils.rotate("abcdefg", -9)  = "cdefgab"
        System.out.println("Reverse/ReverseDelimited - reverses a String");
        System.out.println("Abbreviate - abbreviates a string using ellipsis or another given String");
        System.out.println("Difference - compares Strings and reports on their differences");
        System.out.println("LevenshteinDistance - the number of changes needed to change one String into another");


        System.out.println("将字符串重复n次，将文字按某宽度居中，将字符串数组用某字符串连接.");
        String[] header = new String[3];
        header[0] = StringUtils.repeat("*", 50);
        header[1] = StringUtils.center("  StringUtilsDemo  ", 50, "^O^");
        header[2] = header[0];
        String head = StringUtils.join(header, "/n");
        System.out.println(head);

        System.out.println("缩短到某长度,用...结尾.");
        System.out.println(StringUtils.abbreviate(
                "The quick brown fox jumps over the lazy dog.", 10));
        System.out.println(StringUtils.abbreviate(
                "The quick brown fox jumps over the lazy dog.", 15, 10));

        System.out.println("返回两字符串不同处索引号.");
        System.out.println(StringUtils.indexOfDifference("aaabc", "aaacc"));

        System.out.println("返回两字符串不同处开始至结束.");
        System.out.println(StringUtils.difference("aaabcde", "aaaccde"));

        System.out.println("截去字符串为以指定字符串结尾的部分.");
//        System.out.println(StringUtils.chomp("aaabcde", "de"));//Deprecated.
        System.out.println(StringUtils.removeEnd("aaabcde","de"));//aaabc
        System.out.println(StringUtils.removeEndIgnoreCase("aaabcde","dE"));//aaabc
        System.out.println(StringUtils.chop("aaabcde"));//aaabcd

        System.out.println("检查一字符串是否为另一字符串的子集.");
        System.out.println(StringUtils.containsOnly("aad", "aadd"));

        System.out.println("检查一字符串是否不是另一字符串的子集.");
        System.out.println(StringUtils.containsNone("defg", "aadd"));

        System.out.println("检查一字符串是否包含另一字符串.");
        System.out.println(StringUtils.contains("defg", "ef"));
        System.out.println(StringUtils.containsOnly("ef", "defg"));

        System.out.println("返回可以处理null的toString().");
        System.out.println(StringUtils.defaultString("aaaa"));
        System.out.println("?" + StringUtils.defaultString(null) + "!");

        System.out.println("去除字符中的空格.");
        System.out.println(StringUtils.deleteWhitespace("aa  bb  cc"));

        System.out.println("判断是否是某类字符.");
        System.out.println(StringUtils.isAlpha("ab"));
        System.out.println(StringUtils.isAlphanumeric("12"));
        System.out.println(StringUtils.isBlank(""));
        System.out.println(StringUtils.isNumeric("123"));
    }

    /**
     * SystemUtilss
     */
    @Test
    public void systemUtilsDemo() {
        System.out.println(genHeader("SystemUtils"));
        System.out.println("获得系统文件分隔符.");
        System.out.println(SystemUtils.FILE_SEPARATOR);

        System.out.println("获得源文件编码.");
        System.out.println(SystemUtils.FILE_ENCODING);

        System.out.println("获得ext目录.");
        System.out.println(SystemUtils.JAVA_EXT_DIRS);

        System.out.println("获得java版本.");
        System.out.println(SystemUtils.JAVA_VM_VERSION);

        System.out.println("获得java厂商.");
        System.out.println(SystemUtils.JAVA_VENDOR);
    }

    /**
     * ClassUtils
     */
    @Test
    public void classUtilsDemo() {
        System.out.println(genHeader("ClassUtils"));
        System.out.println("获取类实现的所有接口.");
        System.out.println(ClassUtils.getAllInterfaces(Date.class));

        System.out.println("获取类所有父类.");
        System.out.println(ClassUtils.getAllSuperclasses(Date.class));

        System.out.println("获取简单类名.");
        System.out.println(ClassUtils.getShortClassName(Date.class));

        System.out.println("获取包名.");
        System.out.println(ClassUtils.getPackageName(Date.class));

        System.out.println("判断是否可以转型.");
        System.out.println(ClassUtils.isAssignable(Date.class, Object.class));
        System.out.println(ClassUtils.isAssignable(Object.class, Date.class));
    }

    /**
     * FieldUtils
     */
    @Test
    public void fieldUtilsDemo() {
        System.out.println(FieldUtils.getAllFields(Date.class));
        System.out.println(FieldUtils.getAllFieldsList(Date.class));
        System.out.println(FieldUtils.getField(Date.class,"fastTime"));
    }

    /**
     * StringEscapeUtils 被commons-text StringEscapeUtils 替代
     */
//    public void stringEscapeUtilsDemo() {
//        System.out.println(genHeader("StringEcsapeUtils"));
//        System.out.println("转换特殊字符.");
//        System.out.println("html:" + StringEscapeUtils.escapeHtml4("/n\n"));
//        System.out.println("html:"
//                + StringEscapeUtils.unescapeHtml4("<p>"));
//    }

    private final class BuildDemo {
        String name;

        int age;

        public BuildDemo(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String toString() {
            ToStringBuilder tsb = new ToStringBuilder(this,
                    ToStringStyle.MULTI_LINE_STYLE);
            tsb.append("Name", name);
            tsb.append("Age", age);
            return tsb.toString();
        }

        public int hashCode() {
            HashCodeBuilder hcb = new HashCodeBuilder();
            hcb.append(name);
            hcb.append(age);
            return hcb.hashCode();
        }

        public boolean equals(Object obj) {
            if (!(obj instanceof BuildDemo)) {
                return false;
            }
            BuildDemo bd = (BuildDemo) obj;
            EqualsBuilder eb = new EqualsBuilder();
            eb.append(name, bd.name);
            eb.append(age, bd.age);
            return eb.isEquals();
        }
    }

    public void builderDemo() {
        System.out.println(genHeader("BuilderDemo"));
        BuildDemo obj1 = new BuildDemo("a", 1);
        BuildDemo obj2 = new BuildDemo("b", 2);
        BuildDemo obj3 = new BuildDemo("a", 1);

        System.out.println("toString()");
        System.out.println(obj1);
        System.out.println(obj2);
        System.out.println(obj3);

        System.out.println("hashCode()");
        System.out.println(obj1.hashCode());
        System.out.println(obj2.hashCode());
        System.out.println(obj3.hashCode());

        System.out.println("equals()");
        System.out.println(obj1.equals(obj2));
        System.out.println(obj1.equals(obj3));
    }

    /**
     * NumberUtils
     */
    public void numberUtils() {
        System.out.println(genHeader("NumberUtils"));
        System.out.println("字符串转为数字(不知道有什么用).");
        System.out.println(NumberUtils.toInt("ba", 33));

        System.out.println("从数组中选出最大值.");
        System.out.println(NumberUtils.max(new int[]{1, 2, 3, 4}));

        System.out.println("判断字符串是否全是整数.");
        System.out.println(NumberUtils.isDigits("123.1"));

        System.out.println("判断字符串是否是有效数字.");
        System.out.println(NumberUtils.isNumber("0123.1"));
    }

    /**
     * DateFormatUtils
     */
    public void dateFormatUtilsDemo() {
        System.out.println(genHeader("DateFormatUtilsDemo"));
        System.out.println("格式化日期输出.");
        System.out.println(DateFormatUtils.format(System.currentTimeMillis(),
                "yyyy-MM-dd HH:mm:ss"));

        System.out.println("秒表.");
        StopWatch sw = new StopWatch();
        sw.start();

        for (Iterator iterator = DateUtils.iterator(new Date(),
                DateUtils.RANGE_WEEK_CENTER); iterator.hasNext(); ) {
            Calendar cal = (Calendar) iterator.next();
            System.out.println(DateFormatUtils.format(cal.getTime(),
                    "yy-MM-dd HH:mm"));
        }

        sw.stop();
        System.out.println("秒表计时:" + sw.getTime());

    }

    private String genHeader(String head) {
        String[] header = new String[3];
        header[0] = StringUtils.repeat("*", 50);
        header[1] = StringUtils.center("  " + head + "  ", 50, "^O^");
        header[2] = header[0];
        return StringUtils.join(header, "/n");
    }



}
